package com.example.score.service;

import com.example.score.entity.ClassInfo;
import com.example.score.entity.ExamDetail;
import com.example.score.entity.StudentSubmit;
import com.example.score.mapper.ClassInfoMapper;
import com.example.score.mapper.ExamDetailMapper;
import com.example.score.mapper.StudentSubmitMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ScoreOverviewService {
    private final ClassInfoMapper classInfoMapper;
    private final StudentSubmitMapper studentSubmitMapper;
    private final ExamDetailMapper examDetailMapper;

    public Map<String, Object> calculateScoreOverview(Long examId, Long classId) {
        Map<String, Object> result = new HashMap<>();

        // 1. 先查询考试详情
        ExamDetail examDetail = examDetailMapper.selectByExamId(examId);
        if (examDetail == null) {
            log.error("未找到考试详情数据: examId={}", examId);
            throw new RuntimeException("未找到考试详情数据");
        }

        if (classId == null || classId == 0) {
            // 2. 查询该考试详情下的所有班级
            List<ClassInfo> classInfos = classInfoMapper.selectByExamDetailId(examDetail.getId());
            List<Map<String, Object>> classes = new ArrayList<>();

            for (ClassInfo classInfo : classInfos) {
                Map<String, Object> classData = calculateClassStatistics(classInfo);
                classes.add(classData);
            }

            Map<String, Object> grade = calculateGradeStatistics(classInfos);
            result.put("classes", classes);
            result.put("grade", grade);
        } else {
            // 3. 查询指定班级
            ClassInfo classInfo = classInfoMapper.selectByExamDetailIdAndClassId(examDetail.getId(), classId);
            if (classInfo == null) {
                log.error("未找到班级数据: examDetailId={}, classId={}", examDetail.getId(), classId);
                throw new RuntimeException("未找到班级数据");
            }
            List<Map<String, Object>> classes = new ArrayList<>();
            classes.add(calculateClassStatistics(classInfo));
            result.put("classes", classes);
        }

        return result;
    }

    private Map<String, Object> calculateClassStatistics(ClassInfo classInfo) {
        Map<String, Object> classData = new HashMap<>();
        classData.put("className", classInfo.getClassName());
        classData.put("classId", classInfo.getClassId());

        // 获取该班级的所有学生提交记录
        List<StudentSubmit> studentSubmits = studentSubmitMapper.selectByClassInfoId(classInfo.getExamDetailId(), classInfo.getId());

        // 计算统计数据
        ExamDetail examDetail = examDetailMapper.selectById(classInfo.getExamDetailId());
        int fullScore = examDetail != null ? examDetail.getFullScore() : 100;

        classData.put("fullScore", fullScore);
        classData.put("maxScore", String.format("%.2f", calculateMaxScore(studentSubmits)));
        classData.put("averageScore", String.format("%.2f", calculateAverageScore(studentSubmits)));
        classData.put("excellentRate", String.format("%.2f", calculateExcellentRate(studentSubmits, fullScore)));
        classData.put("passRate", String.format("%.2f", calculatePassRate(studentSubmits, fullScore)));
        classData.put("medianScore", String.format("%.2f", calculateMedianScore(studentSubmits)));
        classData.put("standardDeviation", String.format("%.2f", calculateStandardDeviation(studentSubmits)));

        return classData;
    }

    private Map<String, Object> calculateGradeStatistics(List<ClassInfo> classInfos) {
        Map<String, Object> grade = new HashMap<>();
        List<StudentSubmit> allStudentSubmits = new ArrayList<>();

        // 收集所有班级的学生提交记录
        for (ClassInfo classInfo : classInfos) {
            allStudentSubmits.addAll(studentSubmitMapper.selectByClassInfoId(classInfo.getExamDetailId(), classInfo.getId()));
        }

        // 获取考试满分
        ExamDetail examDetail = null;
        if (!classInfos.isEmpty()) {
            examDetail = examDetailMapper.selectById(classInfos.get(0).getExamDetailId());
        }
        int fullScore = examDetail != null ? examDetail.getFullScore() : 100;

        grade.put("fullScore", fullScore);
        grade.put("maxScore", String.format("%.2f", calculateMaxScore(allStudentSubmits)));
        grade.put("averageScore", String.format("%.2f", calculateAverageScore(allStudentSubmits)));
        grade.put("excellentRate", String.format("%.2f", calculateExcellentRate(allStudentSubmits, fullScore)));
        grade.put("passRate", String.format("%.2f", calculatePassRate(allStudentSubmits, fullScore)));
        grade.put("medianScore", String.format("%.2f", calculateMedianScore(allStudentSubmits)));
        grade.put("standardDeviation", String.format("%.2f", calculateStandardDeviation(allStudentSubmits)));

        return grade;
    }

    private double calculateMaxScore(List<StudentSubmit> submits) {
        return Math.round(submits.stream()
                .mapToDouble(StudentSubmit::getScore)
                .max()
                .orElse(0) * 100.0) / 100.0;
    }

    private double calculateAverageScore(List<StudentSubmit> submits) {
        return Math.round(submits.stream()
                .mapToDouble(StudentSubmit::getScore)
                .average()
                .orElse(0) * 100.0) / 100.0;
    }

    private double calculateExcellentRate(List<StudentSubmit> submits, int fullScore) {
        if (submits.isEmpty()) {
            return 0.00;
        }
        double excellentThreshold = fullScore * 0.85; // 85分以上为优秀
        long excellentCount = submits.stream()
                .filter(s -> s.getScore() >= excellentThreshold)
                .count();
        return Math.round((excellentCount * 100.0 / submits.size()) * 100.0) / 100.0;
    }

    private double calculatePassRate(List<StudentSubmit> submits, int fullScore) {
        if (submits.isEmpty()) {
            return 0.00;
        }
        double passThreshold = fullScore * 0.60; // 60分及格
        long passCount = submits.stream()
                .filter(s -> s.getScore() >= passThreshold)
                .count();
        return Math.round((passCount * 100.0 / submits.size()) * 100.0) / 100.0;
    }

    private double calculateMedianScore(List<StudentSubmit> submits) {
        if (submits.isEmpty()) {
            return 0.00;
        }
        List<Double> scores = submits.stream()
                .map(StudentSubmit::getScore)
                .sorted()
                .collect(Collectors.toList());
        int size = scores.size();
        double median;
        if (size % 2 == 0) {
            median = (scores.get(size / 2 - 1) + scores.get(size / 2)) / 2.0;
        } else {
            median = scores.get(size / 2);
        }
        return Math.round(median * 100.0) / 100.0;
    }

    private double calculateStandardDeviation(List<StudentSubmit> submits) {
        if (submits.isEmpty()) {
            return 0.00;
        }
        double mean = calculateAverageScore(submits);
        double variance = submits.stream()
                .mapToDouble(s -> Math.pow(s.getScore() - mean, 2))
                .average()
                .orElse(0);
        return Math.round(Math.sqrt(variance) * 100.0) / 100.0;
    }
} 